home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-06-19 | 4.1 KB | 151 lines | [TEXT/CWIE] |
- /*
- Problem 01 - Mode Sort
-
- This problem is to sort an input string of N characters, N<1000000, based on
- the number of times a character occurs in the input. The most frequently
- occurring character should be sorted to the front of the string, followed by
- the next most frequently occurring character, etc. For characters occurring
- the same number of times, the character that occurs first in the input should
- be sorted to the front.
-
- Header specification
-
- pascal OSErr ModeSort( const FSSpec* infile, const FSSpec* outfile );
-
- Input specification
-
- The infile input file contains the characters. Input characters other than
- those printable low ascii characters c, 0x20<c<0x7f, must be ignored.
-
- Output specification
-
- The outfile must be created and then filled with the sorted characters. It's
- final length should be exactly the same as the count of characters in the
- allowed range (0x20<c<0x7f) (which may be shorter than the infile file length).
-
- Sample input
-
- abcdefghabbcccdddeee
- or
- 012345678911234567892123456789312345678941234567895123456789612345678971234567891
-
- Sample output
-
- ccccddddeeeebbbaafgh
- or
- 111111111122222222233333333344444444455555555566666666677777777788888888999999990
- */
-
- #include "Solution.h"
-
- // Fill in your solution and then submit this folder
- // Team Name: Team Guinness
-
- static unsigned char seenfirst(unsigned char orderseen[0x100], int x, int y)
- {
- int i;
- for (i=0; i<0x100; i++)
- {
- if (orderseen[i] == x) return(x);
- if (orderseen[i] == y) return(y);
- }
- return(0);
- }
-
- static unsigned char findmostcommon(unsigned long h[0x100], unsigned char orderseen[0x100])
- {
- int best = 0, i;
- for (i=1; i<0x100; i++)
- {
- if (h[best] < h[i]) best = i;
- else if (h[best] == h[i] && seenfirst(orderseen, i, best) == i) best = i;
- }
- return(best);
- }
-
- pascal OSErr ModeSort( const FSSpec* infile, const FSSpec* outfile )
- {
- int i, j, uniquenumseen = 0;
- Ptr InPtr = NULL;
- Ptr InEnd = NULL;
- OSErr err = noErr;
- short ReadRefNum = 0, WriteRefNum = 0;
- long BytesRemaining = 0;
- unsigned long histogram[0x100];
- unsigned char charseen[0x100], orderseen[0x100];
-
- for (i=0; i<0x100; i++) histogram[i] = charseen[i] = orderseen[i] = 0;
-
- // Allocate some storage
- unsigned long BufferSize = MaxBlock();
- Handle Buffer = NewHandle(BufferSize);
- while (!Buffer && BufferSize > 1024)
- { BufferSize >>= 1; Buffer = NewHandle(BufferSize); }
- if (!Buffer) return(MemError());
- HLock(Buffer);
-
- err = FSpOpenDF(infile, fsRdPerm, &ReadRefNum);
- if (err) goto exit;
-
- err = GetEOF(ReadRefNum, &BytesRemaining);
- if (err) goto exit;
-
- while (BytesRemaining)
- {
- // Grab some bytes from the file
- long inOutCount = BytesRemaining;
- if (inOutCount > BufferSize) inOutCount = BufferSize;
- err = FSRead(ReadRefNum, &inOutCount, *Buffer);
- if (err) goto exit;
- if (inOutCount == 0) { DebugStr("\pError: FSRead read nothing"); goto exit; }
- InPtr = *Buffer;
- InEnd = InPtr + inOutCount;
- BytesRemaining -= inOutCount;
-
- // Munch on the bytes
- while (InPtr < InEnd)
- {
- unsigned char c = *InPtr++;
- if (c > 0x20 && c < 0x7F)
- {
- if (!charseen[c]) { charseen[c] = 1; orderseen[uniquenumseen++] = c; }
- histogram[c]++;
- }
- }
- }
-
- FSClose(ReadRefNum); ReadRefNum = 0;
-
- // Make sure output file exists (will give error if it already exists)
- FSpCreate(outfile, 'CWIE', 'TEXT', 0);
-
- err = FSpOpenDF(outfile, fsWrPerm, &WriteRefNum);
- if (err) goto exit;
-
- err = SetEOF(WriteRefNum, 0);
- if (err) goto exit;
-
- for (i=0; i<0x100; i++)
- {
- unsigned char c = findmostcommon(histogram, orderseen);
- long inOutCount = histogram[c];
- if (inOutCount > BufferSize) inOutCount = BufferSize;
- for (j=0; j<inOutCount; j++) Buffer[0][j] = c;
- while (histogram[c])
- {
- long inOutCount = histogram[c];
- if (inOutCount > BufferSize) inOutCount = BufferSize;
- err = FSWrite(WriteRefNum, &inOutCount, *Buffer);
- if (err) goto exit;
- if (inOutCount == 0) { DebugStr("\pError: FSWrite wrote nothing"); goto exit; }
- histogram[c] -= inOutCount;
- }
- }
-
- exit:
- if (WriteRefNum) FSClose(WriteRefNum);
- if (ReadRefNum) FSClose(ReadRefNum);
- if (Buffer) DisposeHandle(Buffer);
- return(err);
- }
-